home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
TCL1
/
JOHNLOVE
/
C_SOURCE
/
CMYMISC.C
< prev
next >
Wrap
Text File
|
1992-02-24
|
18KB
|
715 lines
/*********************************************************
"CmyMisc.c"
by John A. Love, III [Washington Apple Pi Users' Group]
using Symantec's "THINK C", v 5.0.1
... as derived from their "TCL Starter" files
*********************************************************/
#include <CDesktop.h>
#include <CDecorator.h>
#include <CScrollPane.h>
#include <CWindow.h>
#include <OSChecks.h>
#include <Sound.h>
#include <Traps.h>
#include <LongQD.h>
#include <TCLUtilities.h>
#include "CmyGlobals.h"
#include "CmyMisc.h"
extern tSystem gSystem;
extern CDesktop *gDesktop;
extern CDecorator *gDecorator;
void CSpiffyGraphics::ISystem7Braggart (CApplication *itsSupervisor) {
/* Note that we do NOT bother to pass a printable parm to this routine
** because we'll set it to false when we call IDocument.
** Print a splash screen -- you've got to be kidding ?!*!? */
short kSystem7 = 777;
// TRY -- TRY-CATCH-ENDTRY @ top of calling sequence.
{
CDocument::IDocument(itsSupervisor, false);
itsWindow = new (CWindow);
/* FailNIL(itsWindow); -- done by new() */
itsWindow->IWindow(kSystem7, false, gDesktop, this);
// Already centered by System 7:
// gDecorator->CenterWindow(itsWindow);
}
/* CATCH
{
SysBeep(10);
SysBeep(10);
DisposeSystem7Braggart();
}
ENDTRY; */
} /* ISystem7Braggart */
void CSpiffyGraphics::DisplaySystem7Braggart (void) {
Boolean savedAlloc;
short kSystem7 = 777;
Rect wpRect, picRect;
PicHandle myPic;
long finalTicks;
// itsWindow->Select(); -- called by IWindow since WIND rsrc is visible.
itsWindow->Prepare();
savedAlloc = SetAllocation(kAllocCanFail);
myPic = GetPicture(kSystem7);
SetAllocation(savedAlloc);
FailNILRes(myPic);
/* If we've gotten this far, we have a pict: */
wpRect = itsWindow->macPort->portRect;
picRect = wpRect;
InsetRect(&picRect, 1, 1);
DrawPicture(myPic, &picRect); // ... so it's centered.
Delay(60, &finalTicks);
InvertRect(&wpRect);
Delay(120, &finalTicks);
ReleaseResource(myPic);
} /* DisplaySystem7Braggart */
void CSpiffyGraphics::DisposeSystem7Braggart (void) {
inherited::Dispose();
} /* DisposeSystem7Braggart */
void CSpiffyGraphics::ISpiffyIris (CApplication *itsSupervisor) {
short bragWindowID = 999;
Rect bragRect;
LongRect onScreen;
CmyBitMap *braggart = NULL;
CDocument::IDocument(itsSupervisor, false);
bragOSBMPane = nil; // In case we bomb early ...
centeredPic = nil;
itsWindow = new (CWindow);
itsWindow->IWindow(bragWindowID, false, gDesktop, this);
/* -------------------------------------------------------
** We will be placing a PICTure into an off screen BitMap.
** If itsBitMap = NULL, then ImyBitMapPane calls:
** new (CmyBitMap)
** IBitMap and
** itsBitMap->SetBoundsOrigin(...)
** ------------------------------------------------------- */
bragRect = itsWindow->macPort->portRect;
QDToLongRect(&bragRect, &onScreen);
bragOSBMPane = new (CmyBitMapPane);
bragOSBMPane->itsBitMap = braggart;
bragOSBMPane->ImyBitMapPane(
itsWindow, /* = itsEnclosure (CView) */
this, /* = CBureaucrat = this doc */
0, 0, 0, 0,
sizELASTIC, sizELASTIC,
&onScreen,
braggart,
true /* makePort */
);
itsMainPane = bragOSBMPane; /* CDocument instance variable. */
bragOSBMPane->FitToEnclosure(true, true);
/* System 7 WIND resource automatically centers: */
if ( !WINDResourceHasSystem7Field(itsWindow) ) {
short saveProcID = itsWindow->procID;
itsWindow->SetModal(false);
// Gotta do this kludge because CenterWindow tests isModal
// AND the window's procID:
itsWindow->procID = 0;
gDecorator->CenterWindow(itsWindow);
itsWindow->procID = saveProcID;
}
} /* ISpiffyIris */
void CSpiffyGraphics::DisplaySpiffyIris (void) {
Boolean savedAlloc;
CmyBitMap *myBitMap;
short IACS = 3001;
PicHandle logoPicHdl;
short maskPercent;
RgnHandle irisRgn;
long finalTicks, tempX, tempY;
Rect pictRect, bragRect, tempShortR;
LongRect offScreen, onScreen, tempLongR, irisRect;
itsWindow->Select();
itsMainPane->Prepare();
savedAlloc = SetAllocation(kAllocCanFail);
logoPicHdl = GetPicture(IACS);
SetAllocation(savedAlloc);
FailNILRes(logoPicHdl);
bragRect = itsWindow->macPort->portRect;
pictRect = (**logoPicHdl).picFrame; // Center the PICT ...
CenterRects(&pictRect, &bragRect);
// Make a new PICT, this one centered & clipped to my portRect:
ClipRect(&bragRect);
centeredPic = OpenPicture(&bragRect);
ClipRect(&bragRect);
EraseRect(&bragRect);
InvertRect(&bragRect);
DrawPicture(logoPicHdl, &pictRect);
ClosePicture();
;
MoveHHi(centeredPic);
HLock(centeredPic);
ReleaseResource(logoPicHdl); /* Kiss the original good-bye !! */
myBitMap = (CmyBitMap*) bragOSBMPane->GetBitMap();
myBitMap->GetBounds(&offScreen); /* = local screen coordinates */
myBitMap->BeginDrawing();
LClipRect(&offScreen); /* Draw off-screen ... */
LEraseRect(&offScreen); /* Eliminate all stray matter. */
tempLongR = offScreen;
LongToQDRect(&tempLongR, &tempShortR);
DrawPicture(centeredPic, &tempShortR);
myBitMap->EndDrawing();
// bragRect = itsWindow->macPort->portRect;
QDToLongRect(&bragRect, &onScreen);
LClipRect(&onScreen);
// LInvertRect(&onScreen); /* Part of centeredPic. */
BackColor(whiteColor);
ForeColor(blackColor);
/* ---------- */
maskPercent = 99; /* Initialize some stuff ... */
tempX = (onScreen.right - onScreen.left) / 2;
tempY = (onScreen.bottom - onScreen.top) / 2;
myBitMap->SetXferMode(srcCopy);
while (maskPercent >= 0) {
irisRect = onScreen;
InsetLongRect(&irisRect,
(tempX * maskPercent) / 100,
(tempY * maskPercent) / 100);
irisRgn = NewRgn();
OpenRgn();
{
LFrameRoundRect(
&irisRect,
((irisRect.right - irisRect.left) * maskPercent) / 100,
((irisRect.bottom - irisRect.top) * maskPercent) / 100
);
}
CloseRgn(irisRgn);
SectRgn(irisRgn, myBitMap->savePort->visRgn, irisRgn);
myBitMap->CopyFrom(&offScreen, &onScreen, irisRgn);
DisposeRgn(irisRgn);
;
if (gSystem.hasColorQD) Delay(3, &finalTicks);
else Delay(1, &finalTicks);
;
maskPercent--;
} /* while maskPercent >= 0 */
/* ---------- */
Delay(180, &finalTicks); /* Take a gander at its beauty, folks !!! */
} /* DisplaySpiffyIris */
void CSpiffyGraphics::DisposeSpiffyIris (void) {
if (centeredPic != nil) {
HUnlock(centeredPic);
KillPicture(centeredPic);
}
if (bragOSBMPane) bragOSBMPane->Dispose();
inherited::Dispose();
} /* DisposeSpiffyIris */
void CSpiffyGraphics::ISpiffyScroll (CApplication *itsSupervisor) {
Boolean savedAlloc;
short kWAP = 3002, pScale = 12, saveProcID;
Str255 windTitle;
// CPicture *pict; -- in class description.
PicHandle myPic;
CScrollPane *scrollPn;
Rect pictRect, paneRect;
CDocument::IDocument(itsSupervisor, false);
/* I could later call CPicture::UsePICT, but I still need the PICT's
** frame to dynamically alter the window size to accomodate the
** PICT. Since I need to call _GetPicture to retrieve this frame,
** I finish off duplicating UsePICT by calling SetMacPicture below: */
savedAlloc = SetAllocation(kAllocCanFail);
myPic = GetPicture(kWAP);
SetAllocation(savedAlloc);
FailNILRes(myPic);
pictRect = (**myPic).picFrame;
itsWindow = new (CWindow);
itsWindow->IWindow(kWAP, false, gDesktop, this);
itsWindow->GetTitle(windTitle);
scrollPn = new (CScrollPane);
scrollPn->IScrollPane(itsWindow, this, /* standard stuff ... */
0, 0, 0, 0, sizELASTIC, sizELASTIC,
false, /* no horizontal scroll bar */
false, /* no vertical scroll bar */
false /* no size box */ );
scrollPn->FitToEnclosure(true, true);
pict = new (CPicture);
pict->IPicture(scrollPn, this, 0, 0, 0, 0, sizELASTIC, sizELASTIC);
itsMainPane = pict;
itsGopher = pict;
/* The enclosure will NOT include any of the Scroll Bars.
** In this case, however, we stipulated there were none. */
pict->FitToEnclosure(true, true);
pict->SetMacPicture(myPic);
/* Stipulate that PICT will be drawn to original size,
** NOT sized to fit the frame of the Scroll Pane: */
pict->SetScaled(false);
pict->SetScales(pScale, pScale);
;
scrollPn->InstallPanorama(pict);
/* Alters the size of all sub-views which now include
** the scroll pane and its associated panorama: */
itsWindow->ChangeSize(
Max( 2*(pictRect.right - pictRect.left), StringWidth(windTitle) ),
2*(pictRect.bottom - pictRect.top)
);
LongToQDRect(&itsMainPane->frame, &paneRect);
CenterRects(&pictRect, &paneRect);
/* Set the initial drawing of the PICT at the center of window:
**
** Note that we scroll the pane UP in order to scroll the
** panorama DOWN and vice-versa. This is directly analogous to
** clicking on the UP scroll arrow of a ScrollBar and seeing the
** text scroll DOWN.
**
** Note also that the picture will NOT be scrolled at all if we
** had called SetScaled(true) above because in this instance the
** offseting of the frame in CScrollPane::DoScroll equals the
** offseting of the port's origin. As a result, the picture's
** topLeft point will still be at the topLeft of the port. */
scrollPn->DoScroll(- (long) pictRect.left/pict->hScale,
- (long) pictRect.top /pict->vScale);
// ChangeSize destroys the prep work done by System 7:
// if ( !WINDResourceHasSystem7Field(itsWindow) ) {
itsWindow->SetModal(false);
// Gotta do this kludge because CenterWindow tests isModal
// AND the window's procID:
saveProcID = itsWindow->procID;
itsWindow->procID = 0;
gDecorator->CenterWindow(itsWindow);
itsWindow->procID = saveProcID;
// }
} /* ISpiffyScroll */
void CSpiffyGraphics::DisplaySpiffyScroll (void) {
LongPt thePosition;
LongRect theFrame;
PicHandle thePICT;
Rect pictRect;
long DH, DV, finalTicks;
// Initial position, centered, is negative:
pict->GetPosition(&thePosition);
itsWindow->GetFrame(&theFrame);
thePICT = pict->GetMacPicture();
pictRect = (**thePICT).picFrame;
DH = - (theFrame.right - (pictRect.right - pictRect.left))/pict->hScale;
DV = - (theFrame.bottom - (pictRect.bottom - pictRect.top ))/pict->vScale;
itsWindow->Select();
itsMainPane->Prepare();
itsWindow->Update(); /* ... so the initially centered PICT gets drawn. */
Delay(45, &finalTicks);
while (thePosition.h != 0) { /* Scroll to left edge. */
if (AnyKeyHasBeenPressed()) return;
if (MouseHasBeenClicked()) break;
pict->itsScrollPane->DoScroll(1, 0);
pict->GetPosition(&thePosition);
Delay(10, &finalTicks);
}
while (thePosition.v != 0) { /* Scroll up to topLeft corner. */
if (AnyKeyHasBeenPressed()) return;
if (MouseHasBeenClicked()) break;
pict->itsScrollPane->DoScroll(0, 1);
pict->GetPosition(&thePosition);
Delay(10, &finalTicks);
}
while (true) /* ... and around and around she goes ... */ {
while (thePosition.h > DH) { /* -> topRight */
if (AnyKeyHasBeenPressed()) return;
if (MouseHasBeenClicked()) break;
pict->itsScrollPane->DoScroll(-1, 0);
pict->GetPosition(&thePosition);
Delay(10, &finalTicks);
}
while (thePosition.v > DV) { /* -> bottomRight */
if (AnyKeyHasBeenPressed()) return;
if (MouseHasBeenClicked()) break;
pict->itsScrollPane->DoScroll(0, -1);
pict->GetPosition(&thePosition);
Delay(10, &finalTicks);
}
while (thePosition.h != 0) { /* -> bottomLeft */
if (AnyKeyHasBeenPressed()) return;
if (MouseHasBeenClicked()) break;
pict->itsScrollPane->DoScroll(1, 0);
pict->GetPosition(&thePosition);
Delay(10, &finalTicks);
}
while (thePosition.v != 0) { /* -> topLeft again */
if (AnyKeyHasBeenPressed()) return;
if (MouseHasBeenClicked()) break;
pict->itsScrollPane->DoScroll(0, 1);
pict->GetPosition(&thePosition);
Delay(10, &finalTicks);
}
} /* while (true) */
} /* DisplaySpiffyScroll */
void CSpiffyGraphics::DisposeSpiffyScroll (void) {
pict->Dispose();
inherited::Dispose();
} /* DisposeSpiffyScroll */
Boolean AnyKeyHasBeenPressed (void) {
EventRecord event;
return ( GetNextEvent(keyDownMask, &event) );
} /* AnyKeyHasBeenPressed */
Boolean MouseHasBeenClicked (void) {
EventRecord event;
return ( GetNextEvent(mDownMask, &event) );
} /* MouseHasBeenClicked */
void CenterRects (Rect *srcRect, Rect *withinRect) {
short srcW, srcH, tempX, tempY;
srcW = srcRect->right - srcRect->left;
// within width - source width:
tempX = withinRect->right - withinRect->left - srcW;
srcRect->left = withinRect->left + tempX/2;
srcRect->right = srcRect->left + srcW;
;
srcH = srcRect->bottom - srcRect->top;
// within height - source height:
tempY = withinRect->bottom - withinRect->top - srcH;
srcRect->top = withinRect->top + tempY/2;
srcRect->bottom = srcRect->top + srcH;
} /* CenterRects */
Boolean aDAisUp (WindowPeek macWindow) {
#define MenuListLoc 0xA1C
typedef struct rMenuRec {
MenuHandle menuOH;
short menuLeft; /* Left edge of Menu. */
} rMenuRec;
typedef struct hMenuRec {
MenuHandle menuHOH;
short reserved;
} hMenuRec;
typedef struct MenuList {
short lastMenu; /* Offset to last regular MenuHandle. */
short lastRight; /* Right edge of last Menu's title. */
short mbResID;
rMenuRec rMenu[];
// The following fields are also present:
//
// short lastHMenu; -- Offset from here to last
// hierarchical Menu.
// PixMapHandle menuTitleSave;
// hMenuRec hMenu[]; -- When my daMenu routine is called,
// there are NO hierarchical Menus.
} MenuList, *MenuListPtr, **MenuListHdl;
MenuListHdl MLHdl = (MenuListHdl) (* (long*)MenuListLoc );
short nbrMenusX6, menuCounter, theMenuID;
if ( macWindow && macWindow->windowKind < 0 ) /* IsSystemWindow */ return (true);
else /* Look for DA MENU, with NO window */ {
nbrMenusX6 = (*MLHdl)->lastMenu;
menuCounter = (nbrMenusX6 / 6) - 1;
while (menuCounter >= 0)
{
theMenuID = (* (*MLHdl)->rMenu[menuCounter].menuOH )->menuID;
// Watch out !!! with System 7 ...
// ... the Help Menu (kHMHelpMenuID = -16490) &
// ... the Application Menu (ID = ???)
if ((theMenuID < 0) && (theMenuID >= -16384)) break;
--menuCounter;
} /* scanning the MenuBar */
// I could have used
// daMenu = theMenuID < 0;
// because I KNOW my app has menus. However, to make this routine
// applicable to ANY app, what if ANY app had zip menus and there
// were no DA menus, I would have to initialize with
// theMenuID = 0;
// putting an extra statement in a time-critical "doPeriodic" loop.
return (menuCounter >= 0);
}
} /* aDAisUp */
/* ===============
Play it, Sam !!
=============== */
void PlaySound (Str255 mySound) {
Handle sndHandle;
OSErr discardError;
if (TrapAvailable(_SndPlay))
{
sndHandle = GetNamedResource('snd ', mySound);
if (sndHandle)
{
discardError = SndPlay (nil, sndHandle, false);
ReleaseResource(sndHandle);
}
} /* _SndPlay is implemented */
} /* PlaySound */
long GetStripAddressMask (void) {
/* Adapted from Macintosh Tech Note #213 */
long gLo3Bytes = 0x00FFFFFF;
/* #define _StripAddress = 0xA055; */
long localBiggee;
if (TrapAvailable(_StripAddress))
{
localBiggee = 0xFFFFFFFF;
return((long)StripAddress((Ptr)&localBiggee));
}
else return(gLo3Bytes);
} /* GetStripAddressMask */
Ptr QuickStrip (long *myPtr) {
return((Ptr)((long)myPtr & gStripAddressMask));
} /* QuickStrip */
Boolean WINDResourceHasSystem7Field (CWindow *theWindow) {
Boolean extraField;
short windType, index, rType;
Byte wTitleLength;
Handle rHdl; /* Handle to WIND resource template */
if (!gSystem.hasHelpMgr) extraField = false;
else
{
extraField = false; // Assume NOT there !!
windType = theWindow->procID;
;
for (index = 1; index <= Count1Resources('WIND'); index++)
{
rHdl = Get1IndResource('WIND', index);
if (rHdl == nil) continue;
asm {
move.l rHdl, a0
move.l (a0), a0
move.w 8(a0), rType
; We don't care about the Title itself, ONLY its length !!
; Note also that the "title" addressed here is that
; in the 'WIND' resource which will be different than
; the actual title displayed IF you've called _SetWTitle
; somewhere along the line:
move.b 18(a0), wTitleLength
}
// Compare window types:
if (windType == rType) {
/*
oldType | newType
------- | -------
18 + 1 + len | a) odd length: 18 + 1 + len + 2
| b) even length: 18 + 1 + len + fill byte + 2
*/
if ( GetHandleSize(rHdl) > 18 + 1 + wTitleLength + 1 )
extraField = true;
break;
}
} /* end for-loop */
} // System 7.
return (extraField);
} /* WINDResourceHasSystem7Field */
GDHandle GetMaxAreaDevice (Rect *globalRect) {
/* Find the greatest overlap device for the given global rectangle. */
long area, maxArea;
GDHandle result, device;
Rect intersection;
result = nil;
;
maxArea = 0;
;
device = GetDeviceList();
while (device != nil) {
if (TestDeviceAttribute(device, screenDevice)) {
if (TestDeviceAttribute(device, screenActive)) {
if (SectRect(globalRect, &((**device).gdRect), &intersection)) {
area = (long)(intersection.right - intersection.left) *
(long)(intersection.bottom - intersection.top);
if (area > maxArea) {
result = device;
maxArea = area;
} /* if area > maxArea */
} /* if SectRect ... */
device = GetNextDevice(device);
} /* screenActive */
} /* screenDevice */
} /* while */
return (result);
} /* GetMaxAreaDevice */
/* end: "CmyMisc.c" */